﻿using System;
using System.Web;
using System.Collections;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.Text;
using System.Reflection;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;
using InfoJetSoft.Service.Worker;
using InfoJetSoft.Service.XPath;

//CID 0189 //2010.09.16 //Begin
namespace InfoJetSoft.Service.Manager
{
	//从Manifest.xsf开始分析XSN文件。
    class ManifestLoader
	{
		public static Manifest loadManifest(HttpContext context, InfoJetContext jetContext, XSNConfig xsnConfig)
		{
			//构造Manfiest类。
			Manifest manifest = new Manifest(xsnConfig);
			//设置InfoJetContext，可能是null，为了节省内存。
			manifest.JetContext = jetContext;

            // Erucy: Add Xsn SPFile Id as Manifest Id
            if (jetContext != null && jetContext.Variables != null &&
                jetContext.Variables["InfoBus_XsnId"] != null)
                manifest.Id = Convert.ToString(jetContext.Variables["InfoBus_XsnId"]);

			//提取CAB文件。
			XSNCABWorker.parseXSN(context, jetContext, manifest);

			FormConfiguration.parseFormConfiguration(manifest);

			//----------- XSNManifestParseWorker.parseManifest(manifest);
			CABFile cabFile = CABFileFinder.findCABFile(manifest, "manifest.xsf");
            XmlDocument doc = DOMUtil.buildDoc(cabFile.ByteOutput);
            manifest.Doc = doc;
			manifest.NsResolver = new NamespaceResolver(doc);
			manifest.XsfPrefix = manifest.NsResolver.GetPrefix(JetConstant.URI_XSF);
            //CID 0703 //2010.12.20 //Begin
            manifest.Xsf2Prefix = manifest.NsResolver.GetPrefix(JetConstant.URI_XSF2);
            manifest.Xsf3Prefix = manifest.NsResolver.GetPrefix(JetConstant.URI_XSF3);
            //CID 0703 //2010.12.20 //End
			manifest.CabFile = cabFile;
			manifest.PublishUrl = manifest.Doc.DocumentElement.GetAttribute( "publishUrl" );

            //CID 0945 //2011.06.10 //Begin
            BindingTest bindingTest = null;
            //CID 0876 //2011.05.04 //Begin
            if (ConfigUtil.BindingTest())
            {
                manifest.EnableBindingTest = true;
            }
            //CID 0876 //2011.05.04 //End
            //CID 0948 //2011.06.15 //Begin
            BindingTest.CheckEnabled(manifest);
            //CID 0948 //2011.06.15 //End
            if (manifest.EnableBindingTest)
            {
                //CID 0951 //2011.06.17 //Begin
                XSNManifestParseWorker.parseSampleDataFile(manifest);
                //CID 0951 //2011.06.17 //End
                bindingTest = new BindingTest(manifest);
            }
            //CID 0945 //2011.06.10 //End
			
			XSNManifestParseWorker.parseSolutionVersion(manifest);
			XSNManifestParseWorker.parseSolutionFormatVersion(manifest);
			XSNManifestParseWorker.parseProductVersion(manifest);
            //CID 0703 //2010.12.20 //Begin
            XSNManifestParseWorker.parseRelativeUrlBase(manifest);
            //CID 0703 //2010.12.20 //End
			XSNManifestParseWorker.parseSchemaDefs(manifest);
			XSNManifestParseWorker.parseImportParameters(manifest);
            //CID 0749 //2011.08.30 //Begin
            XSNManifestParseWorker.parseSignedDataBlocks(manifest);
            //CID 0749 //2011.08.30 //End

			//新移动上来的.因为需要将Query,Submit添加到DataAdapterList中.
			XSNTemplateParseWorker.parseTemplate(manifest);
			//parseQuery,parseSubmit needs template.doc, for parsing DataInput.
			XSNManifestParseWorker.parseQuery(context, manifest);
			XSNManifestSubmitParseWorker.parseSubmit(context, manifest);

			//DataObject,Query,Submit是包含DataAdapter的对象.
			XSNManifestDataObjectParseWorker.parseDataObjectList(context, manifest);
			XSNManifestDataAdapterParseWorker.parseDataAdapterList(context, manifest);
            
            
			//CID 0263 //2009.03.31 //Begin
			//RuleSet需要DataAdapter,所以后parseSubmitRuleSet.
			XSNManifestSubmitParseWorker.parseSubmitRuleSet(context, manifest);
			//CID 0263 //2009.03.31 //End

			XSNManifestParseWorker.parseViews(manifest);

            //CID 1704 //2013.04.26 //Begin
            XSNManifestRuleSetParseWorker.postParseSubmitSwitchViews(manifest);
            //CID 1704 //2013.04.26 //End

			XSNManifestParseWorker.parseErrorCondition(manifest);
			XSNManifestXmlToEditParseWorker.parseXmlToEdit(manifest);
            //CID 0858 //2011.03.29 //Begin
            XSNManifestParseWorker.parseErrorBlank(manifest);
            //CID 0858 //2011.04.13 //End
			XSNManifestMenuParseWorker.parseMemu(manifest);
			XSNManifestMenuBuildWorker.buildMenu(manifest);
			XSNManifestDOMEventHandlerParseWorker.parseDOMEventHandler(manifest);
			XSNManifestDOMEventHandlerParseWorker.parseHandlerObject(manifest);
			XSNManifestCalculatedFieldParseWorker.parseCalculatedField(manifest);
			XSNUpgradeBuildWorker.buildUpgrade(manifest);
			
			XSNManifestParseWorker.parseTaskPanes(manifest);
			//-----------

			FormCodeDispatchWorker.load(manifest);
			
			//构造SchemaList，分析Schema引用结构，以便顺利构造SchemaCollection。
			//如去掉循环引用，去掉已经添加到SchemaCollection中Schema的Import，等操作都是基于SchemaLink的。
			SchemaLinkWorker.linkSchema( manifest );
			//清除循环引用的Import。
			SchemaUnlinkWorker.removeRecursion( manifest );
			//构造SchemaSet。
			SchemaSetWorker.buildSchemaSet(manifest);
			//CID 0331 //2009.07.27 //Begin
			SchemaTypeWorker.buildXhtmlFieldNameList(manifest);
			//CID 0331 //2009.07.27 //End

			//parseViewList needs formated SchemaLink.SchemaDoc
            //CID 0945 //2011.06.13 //BindingTest
			ManifestLoader.parseViewList(context, manifest, bindingTest);

			//parseOnLoad needs Manifest.ViewList
			XSNManifestParseWorker.parseOnLoad(manifest);
			//XSNManifestRuleButtonRuleSetParseWorker needs Manifest.ViewList
			XSNManifestRuleButtonRuleSetParseWorker.parseRuleButtonRuleSet(manifest);
			//CID 0235 //2009.03.03 //Begin
			XSNViewFormatHyperlinkWorker.postFormatHyperlink(manifest);
			//CID 0235 //2009.03.03 //End
			XSNManifestRolesParseWorker.parseRoles(manifest);
			XSNBuildQueryXsltWorker.buildQueryXslt(manifest);

            //CID 0825 //2011.03.06 //Begin
            if (manifest.EnableBindingTest)
            {
                bindingTest.TestDefaultValues();
                //CID 0945 //2011.06.14 //Begin
                bindingTest.TestServerControls();
                //CID 0945 //2011.06.14 //End
            }
            //CID 0825 //2011.03.06 //End

			XSNCABWorker.releaseXSN(manifest);

			//CID 0266 //2009.03.31 //Begin
			//在结束注册时再构造View的Xslt,保证使用的ViewDoc是包含所有修改的.
			foreach( View view in manifest.ViewList )
			{
                //CID 0903 //2011.05.30 //Begin
                if (ConfigUtil.PrepareXslt())
                {
                    //CID 0678 //2010.11.03 //Begin
                    view.Xslt = new XCTransform(manifest, view.Doc);
                    //CID 0678 //2010.11.03 //End
                }
                else
                {
                    string viewXml = view.Doc.OuterXml;
                    byte[] content = System.Text.Encoding.UTF8.GetBytes(viewXml);
                    view.Content = content;
                    view.Doc = null;
                }
                //CID 0903 //2011.05.30 //End
			}
			//CID 0266 //2009.03.31 //End

			//CID 0526 //2010.03.30 //Begin
			buildNonProofingNodeNameArrays( manifest );
			//CID 0526 //2010.03.30 //End

			return manifest;
		}

		//CID 0526 //2010.03.30 //Begin
		private static void buildNonProofingNodeNameArrays( Manifest manifest )
		{
			//CID 0517 //2010.03.24 //Begin
			if( ConfigUtil.EnableProofing() )
			{
				Hashtable xmlToEditsByView = new Hashtable();
				foreach( XmlToEdit xmlToEdit in manifest.XmlToEditList )
				{
					if( xmlToEditsByView.ContainsKey( xmlToEdit.ViewName ) )
					{
						ArrayList xmlToEditList = (ArrayList)xmlToEditsByView[ xmlToEdit.ViewName ];
						xmlToEditList.Add( xmlToEdit );
					}
					else
					{
						ArrayList xmlToEditList = new ArrayList();
						xmlToEditList.Add( xmlToEdit );
						xmlToEditsByView.Add( xmlToEdit.ViewName, xmlToEditList );
					}
				}
                //CID 0602 //2010.05.31 //Begin
                foreach (View view in manifest.ViewList)
                {
                    if (!xmlToEditsByView.ContainsKey(view.Name))
                    {
                        xmlToEditsByView.Add( view.Name, new ArrayList() );
                    }
                }
                //CID 0602 //2010.05.31 //End
				StringBuilder noProofingBuffer = new StringBuilder();
				noProofingBuffer.Append( "InfoJet_NonProofingNodeNameArrays = new Array();" );
				foreach( string viewName in xmlToEditsByView.Keys )
				{
					noProofingBuffer.Append( "InfoJet_NonProofingNodeNameArrays['" + viewName + "'] = new Array(" );
					ArrayList xmlToEditList = (ArrayList)xmlToEditsByView[ viewName ];
					foreach( XmlToEdit xmlToEdit in xmlToEditList )
					{
						if( !xmlToEdit.Proofing )
						{
							//CID 0519 //2010.03.26 //Begin
							noProofingBuffer.Append( " '_" );
							//CID 0519 //2010.03.26 //End
							noProofingBuffer.Append( ExpressionUtil.parseTargetNodeName( xmlToEdit.Item ) );
							noProofingBuffer.Append( "'" );
							noProofingBuffer.Append( "," );
						}
					}
					if( noProofingBuffer[ noProofingBuffer.Length - 1 ] == ',' )
					{
						noProofingBuffer.Remove( noProofingBuffer.Length - 1, 1 );
					}
					noProofingBuffer.Append( " );" );
				}	
				manifest.NonProofingNodeNameArrays = noProofingBuffer.ToString();
			}
			//CID 0517 //2010.03.24 //End
		}
		//CID 0526 //2010.03.30 //End

        //遍历Manifest中的ViewList。
        //CID 0945 //2011.06.13 //BindingTest
        public static void parseViewList(HttpContext httpContext, Manifest manifest, BindingTest bindingTest)
        {
            foreach (View view in manifest.ViewList)
            {
                ManifestLoader.parseView(httpContext, manifest, view, bindingTest);
            }
        }

        //分析每个视图，并为Web处理进行格式化。
        //CID 0945 //2011.06.13 //BindingTest
        private static void parseView(HttpContext httpContext, Manifest manifest, View view, BindingTest bindingTest)
        {
            CABFile cabFile = CABFileFinder.findCABFile(manifest, view.Transform);
            XmlDocument doc = DOMUtil.buildDoc(cabFile.ByteOutput);
            view.Doc = doc;
            view.NsResolver = new NamespaceResolver(doc);
            view.XdPrefix = view.NsResolver.GetPrefix(JetConstant.URI_XD);
            view.XslPrefix = view.NsResolver.GetPrefix(JetConstant.URI_XSL);
            //CID 0500 //2010.01.19 //Begin
            view.XdExtensionPrefix = view.NsResolver.GetPrefix(JetConstant.URI_XDEXTENSION);
            //CID 0500 //2010.01.19 //End
            view.CabFile = cabFile;
            XSNViewFormatExprWorker.formatExpr(view);
            XSNViewFormatDTPickerWorker.formatDTPicker(view);
            //CID 0656 //2010.10.11 //Begin
            XSNViewFormatPNGPickerWorker.formatPNGPicker(view);
            //CID 0656 //2010.10.11 //End
            //CID 0657 //2010.12.08 //Begin
            XSNViewFormatEXIPickerWorker.formatEXIPicker(view);
            //CID 0657 //2010.12.08 //End
            XSNViewFormatStyleWorker.formatStyle(httpContext, view);
            //CID 0499 //2010.03.17 //Begin
            XSNViewFormatInkPictureWorker.formatInkPicture(view);
            //CID 0499 //2010.03.17 //End
            XSNViewFormatImageWorker.formatImage(view);
            XSNViewFormatSpanWorker.formatSpan(view);
            XSNViewFormatButtonWorker.formatButton(httpContext, manifest, view);
            XSNViewFormatExpressionBoxWorker.formatExpressionBox(view);
            //CID 0222 //2009.02.04 //Begin
            XSNViewFormatComboBoxWorker.formatComboBox(view);
            //CID 0222 //2009.02.04 //End
            //CID 0638 //2010.08.07 //Begin
            XSNViewFormatHyperlinkBoxWorker.formatHyperlinkBox(view);
            //CID 0638 //2010.08.07 //End
            XSNViewFormatHyperlinkWorker.formatHyperlink(view);
            //CID 0783 //2011.02.16 //Begin
            XSNViewFormatScreenTipAttributesWorker.formatScreenTipAttributes(view);
            //CID 0783 //2011.02.16 //End
            //CID 0800 //2011.03.14 //Begin
            XSNViewFormatSelectWorker.formatSelect(view);
            //CID 0800 //2011.03.14 //End
            XSNViewFormatConditionFormatStyleWorker.formatConditionFormatStyle(view);
            XSNViewFormatConditionFormatAttributeWorker.formatConditionFormatAttribute(view);
            XSNViewFormatPlaceholderButtonWorker.formatPlaceholderButton(view);
            XSNViewFormatTemplateWorker.formatTemplate(view);
            XSNViewFormatTableWorker.formatTable(view);
            XSNViewFormatXdLayoutWorker.formatXdLayout(view);
            XSNViewFormatReadOnlyWorker.formatReadOnly(view);
            //CID 0945 //2011.06.13 //BindingTest
            XSNViewFormatControlWorker.formatControl(view, bindingTest);
            XSNViewFormatHTMLWorker.formatHTML(view);
            XSNViewParseMasterDetialWorker.parseMasterDetial(view);
            XSNViewFormatSignatureWorker.removeSignature(view);
            XSNViewFormatRefreshAfterUpdateWorker.formatRefreshAfterUpdate(view);
            //CID 0467 //2009.11.20 //Begin
            XSNViewFormatNamespaceWorker.formatNamespace(manifest, view);
            //CID 0467 //2009.11.20 //End

            //CID 0272 //2009.04.09 //Begin
            //XSNViewFormatPrintWorker.formatPrint( view );
            //CID 0272 //2009.04.09 //End
        }
	}
}
//CID 0189 //2010.09.16 //End